/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.shop.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.api.YshopException;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.QueryHelpPlus;
import co.yixiang.domain.PageResult;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.enums.OrderInfoEnum;
import co.yixiang.exception.BadRequestException;
import co.yixiang.modules.domain.YxStoreProductStockRecord;
import co.yixiang.modules.order.param.BackstageOrderGoodsParam;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.order.vo.YxStoreOrderQueryVo;
import co.yixiang.modules.product.domain.YxStoreProduct;
import co.yixiang.modules.product.domain.YxStoreProductAttrValue;
import co.yixiang.modules.product.domain.YxStoreSupplier;
import co.yixiang.modules.product.service.YxStoreProductAttrService;
import co.yixiang.modules.product.service.YxStoreProductAttrValueService;
import co.yixiang.modules.product.service.YxStoreSupplierService;
import co.yixiang.modules.product.service.dto.ProductFormatDto;
import co.yixiang.modules.product.service.mapper.StoreProductMapper;
import co.yixiang.modules.product.vo.ProductVo;
import co.yixiang.modules.product.vo.YxStoreProductAttrQueryVo;
import co.yixiang.modules.product.vo.YxStoreProductQueryVo;
import co.yixiang.modules.shop.param.ProductInputFormParam;
import co.yixiang.modules.shop.service.YxStoreProductStockRecordService;
import co.yixiang.modules.shop.service.dto.YxStoreProductStockRecordDto;
import co.yixiang.modules.shop.service.dto.YxStoreProductStockRecordQueryCriteria;
import co.yixiang.modules.shop.service.mapper.YxStoreProductStockRecordMapper;
import co.yixiang.utils.DateUtils;
import co.yixiang.utils.FileUtil;
import co.yixiang.utils.SecurityUtils;
import co.yixiang.utils.moneyChangeUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hdb
 * @date 2024-05-07
 */
@Service
@Slf4j
@AllArgsConstructor
//@CacheConfig(cacheNames = "yxStoreProductStockRecord")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxStoreProductStockRecordServiceImpl extends BaseServiceImpl<YxStoreProductStockRecordMapper, YxStoreProductStockRecord> implements YxStoreProductStockRecordService {

    private final IGenerator generator;

    @Autowired
    private StoreProductMapper storeProductMapper;
    @Autowired
    private YxStoreProductAttrService yxStoreProductAttrService;
    @Autowired
    private YxStoreProductAttrValueService yxStoreProductAttrValueService;
    @Autowired
    private YxStoreSupplierService yxStoreSupplierService;
    private final YxStoreOrderService storeOrderService;


    @Override
    //@Cacheable
    public PageResult<YxStoreProductStockRecordDto> queryAll(YxStoreProductStockRecordQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<YxStoreProductStockRecord> page = new PageInfo<>(queryAll(criteria));
        return generator.convertPageInfo(page, YxStoreProductStockRecordDto.class);
    }


    @Override
    //@Cacheable
    public List<YxStoreProductStockRecord> queryAll(YxStoreProductStockRecordQueryCriteria criteria) {
        return baseMapper.selectList(QueryHelpPlus.getPredicate(YxStoreProductStockRecord.class, criteria));
    }


    @Override
    public void download(List<YxStoreProductStockRecordDto> all, HttpServletResponse response, Integer type) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YxStoreProductStockRecordDto yxStoreProductStockRecord : all) {
            Map<String, Object> map = new LinkedHashMap<>();

            /** 类型，1采购入库单2销售出库单3销售退货单 */
            if (type == 1) {
                map.put("单号", yxStoreProductStockRecord.getRecordSn());
                map.put("采购日期", yxStoreProductStockRecord.getCreateTime());
                map.put("商品名称", yxStoreProductStockRecord.getStoreName());
                map.put("供应商名称", yxStoreProductStockRecord.getSupplierName());
                map.put("单位名", yxStoreProductStockRecord.getUnitName());
                map.put("货号", yxStoreProductStockRecord.getBarCode());
                map.put("数量", yxStoreProductStockRecord.getChangeStockNum());
                map.put("单价", yxStoreProductStockRecord.getPrice());
                map.put("金额", yxStoreProductStockRecord.getPrice().multiply(new BigDecimal(yxStoreProductStockRecord.getChangeStockNum())));
                map.put("采购员", yxStoreProductStockRecord.getCreateBy());
            } else if (type == 2) {
                map.put("订单号", yxStoreProductStockRecord.getOrderId());
                map.put("出单时间", yxStoreProductStockRecord.getCreateTime());
                map.put("客户姓名", yxStoreProductStockRecord.getShopName());
                map.put("所属部门", yxStoreProductStockRecord.getDepartName());
                map.put("商品名称", yxStoreProductStockRecord.getStoreName());
                map.put("单位名", yxStoreProductStockRecord.getUnitName());
                map.put("货号", yxStoreProductStockRecord.getBarCode());
                map.put("数量", yxStoreProductStockRecord.getChangeStockNum());
                map.put("单价", yxStoreProductStockRecord.getPrice());
                map.put("金额", yxStoreProductStockRecord.getPrice().multiply(new BigDecimal(yxStoreProductStockRecord.getChangeStockNum())));
                map.put("付款方式", yxStoreProductStockRecord.getPayTypeName());
                String couponTitle = null;
                if(yxStoreProductStockRecord.getOrderId() != null){
                    YxStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(yxStoreProductStockRecord.getOrderId(),null);
                    if(orderInfo != null ){
                        couponTitle = orderInfo.getCouponTitle();
                    }
                }
                map.put("优惠券", couponTitle);
                map.put("收件人姓名", yxStoreProductStockRecord.getRealName());
                String shippingTypeText = null;
                if (OrderInfoEnum.SHIPPIING_TYPE_1.getValue().equals(yxStoreProductStockRecord.getShippingType())) {
                    shippingTypeText = "快递配送";
                } else if (OrderInfoEnum.SHIPPIING_TYPE_2.getValue().equals(yxStoreProductStockRecord.getShippingType())) {
                    shippingTypeText = "门店自取";
                } else if (OrderInfoEnum.SHIPPIING_TYPE_3.getValue().equals(yxStoreProductStockRecord.getShippingType())) {
                    shippingTypeText = "物流配送";
                }
                map.put("配送方式", shippingTypeText);
                map.put("电话", yxStoreProductStockRecord.getUserPhone());
                map.put("详细地址", yxStoreProductStockRecord.getUserAddress());
                map.put("订单备注", yxStoreProductStockRecord.getRemark());
            } else if (type == 3) {
                map.put("退货单号", yxStoreProductStockRecord.getRecordSn());
                map.put("退货客户", yxStoreProductStockRecord.getStoreName());
                map.put("订单号", yxStoreProductStockRecord.getOrderId());
                map.put("退货日期", yxStoreProductStockRecord.getCreateTime());
                map.put("商品名称", yxStoreProductStockRecord.getStoreName());
                map.put("单位名", yxStoreProductStockRecord.getUnitName());
                map.put("货号", yxStoreProductStockRecord.getBarCode());
                map.put("数量", yxStoreProductStockRecord.getChangeStockNum());
                map.put("单价", yxStoreProductStockRecord.getPrice());
                map.put("金额", yxStoreProductStockRecord.getPrice().multiply(new BigDecimal(yxStoreProductStockRecord.getChangeStockNum())));
                map.put("退货员", yxStoreProductStockRecord.getCreateBy());
                map.put("退货备注", yxStoreProductStockRecord.getRemark());
            }
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void productInputForm(ProductInputFormParam param) {
        List<BackstageOrderGoodsParam> orderGoodsList = param.getSelectProductList();
        String supplierId = param.getSupplierId();
        if (orderGoodsList == null || orderGoodsList.size() == 0) {
            throw new YshopException("请选择商品");
        }
        if (StrUtil.isEmpty(supplierId)) {
            throw new YshopException("请选择供应商");
        }
        for (BackstageOrderGoodsParam orderGoodsParam : orderGoodsList) {
            if (orderGoodsParam.getBuyGoodsNum() == null) {
                throw new YshopException("商品：" + orderGoodsParam.getStoreName() + "，请填写采购入库数");
            }
            if (orderGoodsParam.getBuyGoodsNum() == 0) {
                throw new YshopException("商品：" + orderGoodsParam.getStoreName() + "，请填写采购入库数");
            }
        }
        try {
            /**
             * 遍历选择的商品，生成商品入库记录、更新商品库存数量
             */
            String recordSn = "CG" + DateUtils.dateTimeNow("YYYYMMDDHHMMSS") + RandomUtil.randomNumbers(3);
            for (BackstageOrderGoodsParam orderGoodsParam : orderGoodsList) {
                YxStoreProduct yxStoreProduct = storeProductMapper.selectById(orderGoodsParam.getId());
                //获取商品的库存信息
                YxStoreProductAttrValue storeProductAttrValue = yxStoreProductAttrValueService
                        .getOne(Wrappers.<YxStoreProductAttrValue>lambdaQuery()
                                .eq(YxStoreProductAttrValue::getProductId, yxStoreProduct.getId()).last("limit 1"));
                if (storeProductAttrValue != null) {
                    Map<String, Object> returnMap = yxStoreProductAttrService.getProductAttrDetail(yxStoreProduct.getId());
                    String barCode = (String) returnMap.get("barCode");
                    //新增销售采购入库单，根据订单商品生成
                    YxStoreProductStockRecord storeProductStockRecord = new YxStoreProductStockRecord();
                    storeProductStockRecord.setRecordSn(recordSn);
                    storeProductStockRecord.setType(1);
                    storeProductStockRecord.setProductId(yxStoreProduct.getId());
                    storeProductStockRecord.setStoreName(yxStoreProduct.getStoreName());
                    storeProductStockRecord.setPrice(yxStoreProduct.getPrice());
                    storeProductStockRecord.setUnitName(yxStoreProduct.getUnitName());

                    storeProductStockRecord.setCreateBy(SecurityUtils.getUsername());
                    storeProductStockRecord.setCreateTime(new Date());
                    storeProductStockRecord.setIsDel(0);

                    storeProductStockRecord.setBarCode(barCode);
                    storeProductStockRecord.setBeforeStock(yxStoreProduct.getStock());
                    storeProductStockRecord.setAfterStock(storeProductAttrValue.getStock() + orderGoodsParam.getBuyGoodsNum());
                    Integer changeStockNum = 0;
                    changeStockNum = orderGoodsParam.getBuyGoodsNum();

                    storeProductStockRecord.setChangeStockNum(changeStockNum);
                    String productTotalPriceText = moneyChangeUtil.change(yxStoreProduct.getPrice().multiply(new BigDecimal(changeStockNum)).doubleValue());
                    storeProductStockRecord.setProductTotalPriceText(productTotalPriceText);

                    YxStoreSupplier yxStoreSupplier = yxStoreSupplierService.getById(supplierId);
                    storeProductStockRecord.setSupplierId(yxStoreSupplier.getId());
                    storeProductStockRecord.setSupplierName(yxStoreSupplier.getSupplierName());
                    storeProductStockRecord.setSupplierPhone(yxStoreSupplier.getSupplierPhone());
                    storeProductStockRecord.setSupplierAddress(yxStoreSupplier.getSupplierAddress());

                    //生成商品入库记录
                    this.save(storeProductStockRecord);
                    //更新商品库存数量
                    storeProductAttrValue.setStock(storeProductAttrValue.getStock() + orderGoodsParam.getBuyGoodsNum());
                    yxStoreProduct.setStock(yxStoreProduct.getStock() + orderGoodsParam.getBuyGoodsNum());
                    yxStoreProductAttrValueService.updateById(storeProductAttrValue);
                    storeProductMapper.updateById(yxStoreProduct);
                }
            }
        } catch (Exception e) {
            log.error("后台采购入库异常：" + e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();      //事务回滚
        }
    }

    @Override
    public List<Map<String, Object>> queryRecordListByRecordSn(JSONObject paramObject) {
        List<Map<String, Object>> list = new ArrayList<>();
        String recordSnStr = paramObject.getString("recordSnStr");
        if(StrUtil.isBlank(recordSnStr)){
            throw new BadRequestException("请选择数据");
        }
        List<String> recordSnList = Arrays.asList(recordSnStr.split(","));
        LambdaQueryWrapper<YxStoreProductStockRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(YxStoreProductStockRecord::getRecordSn,recordSnList).orderByDesc(YxStoreProductStockRecord::getCreateTime);
        List<YxStoreProductStockRecord> yxStoreProductStockRecordList = this.baseMapper.selectList(lambdaQueryWrapper);
        //根据
        Map<String, List<YxStoreProductStockRecord>> groupByTableCode = yxStoreProductStockRecordList.stream().collect(Collectors.groupingBy(YxStoreProductStockRecord::getRecordSn));
        // 转换为List并按键排序
        List<Map.Entry<String, List<YxStoreProductStockRecord>>> sortedEntryList = new ArrayList<>(groupByTableCode.entrySet());
        sortedEntryList.sort(Map.Entry.comparingByKey()); // 升序排序
        for (Map.Entry<String, List<YxStoreProductStockRecord>> entry : sortedEntryList) {
            Map<String, Object> map = new HashMap<>();
            String recordSn = entry.getKey();
            List<YxStoreProductStockRecord> recordList = entry.getValue();
            YxStoreProductStockRecord firstRecord = recordList.get(0);

            map.put("recordSn",recordSn);
            map.put("recordList",recordList);
            map.put("nowDate", new Date());
            Long supplierId = firstRecord.getSupplierId();
            String supplierName = firstRecord.getSupplierName();
            String supplierPhone = firstRecord.getSupplierPhone();
            String supplierAddress = firstRecord.getSupplierAddress();
            if(supplierId != null){
                YxStoreSupplier yxStoreSupplier = yxStoreSupplierService.getById(supplierId);
                if(yxStoreSupplier !=null){
                    supplierName = yxStoreSupplier.getSupplierName();
                    supplierPhone = yxStoreSupplier.getSupplierPhone();
                    supplierAddress = yxStoreSupplier.getSupplierAddress();
                }
            }
            map.put("supplierName", supplierName);
            map.put("supplierPhone", supplierPhone);
            map.put("supplierAddress", supplierAddress);
            map.put("remark", firstRecord.getRemark());
            map.put("createBy", firstRecord.getCreateBy());
            BigDecimal payPrice = new BigDecimal("0.00");
            for(YxStoreProductStockRecord record : recordList){
                payPrice = payPrice.add(record.getPrice().multiply(new BigDecimal(record.getChangeStockNum())));
            }
            for(YxStoreProductStockRecord record : recordList){
                record.setPayPrice(payPrice);
            }
            map.put("payPrice", payPrice);
            map.put("productTotalPriceText", firstRecord.getProductTotalPriceText());
            map.put("orderId", firstRecord.getOrderId());
            map.put("payTypeName", firstRecord.getPayTypeName());
            if(firstRecord.getOrderId() != null){
                YxStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(firstRecord.getOrderId(),null);
                if(orderInfo != null ){
                    map.put("couponTitle", orderInfo.getCouponTitle());
                    map.put("couponPrice", orderInfo.getCouponPrice());
                }
            }
            map.put("shippingType", firstRecord.getShippingType());
            map.put("realName", firstRecord.getRealName());
            map.put("userPhone", firstRecord.getUserPhone());
            map.put("userAddress", firstRecord.getUserAddress());
            map.put("shopName", firstRecord.getShopName());
            list.add(map);
        }
        return list;
    }
}
